import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import FileLogger from 'src/utils/file-logger';
import { AuthDocument } from './schemas/auth.schema';
import { SystemUserDocument } from './schemas/system-user.schema';
import {
  CreateAuthType,
  CreateSystemUserType,
  QueryMulAuthsParams,
  QueryMulSystemUserParams,
  QuerySingleAuthParamsType,
  QuerySingleSystemUserParams,
  UpdateAuthType,
  UpdateSystemUserParams,
} from './system-user.interface';

@Injectable()
export class SystemUserService {
  private readonly logger = new FileLogger(SystemUserService.name);
  constructor(
    @InjectModel('SystemUser')
    private systemUserModel: Model<SystemUserDocument>,
    @InjectModel('Auth')
    private authModel: Model<AuthDocument>,
  ) {}

  async querySystemUserList(params, sort) {
    try {
      const { current, pageSize, ...statement } = params;
      const condition: { [key: string]: any } = {};
      if (statement.ownerId) condition.ownerId = statement.ownerId;
      if (statement.userName)
        condition.userName = new RegExp(statement.userName);
      if (statement.account) condition.account = new RegExp(statement.account);
      const total = await this.systemUserModel.countDocuments(condition);
      const data = await this.systemUserModel
        .find(condition)
        .sort(sort)
        .skip(current * pageSize)
        .select({ password: 0 })
        .limit(pageSize);
      return { total, data };
    } catch (err) {
      this.logger.printError(this.querySystemUserList.name, err);
      return { total: 0, data: [] };
    }
  }

  async findOneSystemUser(
    params: QuerySingleSystemUserParams,
    projection: any = null,
  ) {
    try {
      return await this.systemUserModel.findOne(params, projection);
    } catch (err) {
      this.logger.printError(this.findOneSystemUser.name, err);
      return null;
    }
  }
  async findOneAuth(params: QuerySingleAuthParamsType, projection: any = null) {
    try {
      return await this.authModel.findOne(params, projection);
    } catch (err) {
      this.logger.printError(this.findOneAuth.name, err);
      return null;
    }
  }

  async createOneSystemUser(data2create: CreateSystemUserType) {
    try {
      return await this.systemUserModel.create(data2create);
    } catch (err) {
      this.logger.printError(this.createOneSystemUser.name, err);
      return null;
    }
  }

  async createOneAuth(data2create: CreateAuthType) {
    try {
      return await this.authModel.create(data2create);
    } catch (err) {
      this.logger.printError(this.createOneAuth.name, err);
      return null;
    }
  }

  async udpateOneSystemUser(
    params: QuerySingleSystemUserParams,
    data4up: UpdateSystemUserParams,
  ) {
    try {
      const res = await this.systemUserModel.updateOne(params, data4up);
      if (res)
        return await this.systemUserModel.findOne(params, { password: 0 });
      return null;
    } catch (err) {
      this.logger.printError(this.udpateOneSystemUser.name, err);
      return null;
    }
  }

  async updateOneAuth(
    params: QuerySingleAuthParamsType,
    data4up: UpdateAuthType,
  ) {
    try {
      const res = await this.authModel.updateOne(params, {
        $set: data4up,
      });
      if (res) return await this.authModel.findOne(params);
      return null;
    } catch (err) {
      this.logger.printError(this.updateOneAuth.name, err);
      return null;
    }
  }

  async findMulSystemUsers(
    params: QueryMulSystemUserParams,
    projection: any = null,
    limit = 10,
  ) {
    try {
      return await this.systemUserModel
        .find(params)
        .select(projection)
        .limit(limit);
    } catch (err) {
      this.logger.printError(this.findMulSystemUsers.name, err);
      return [];
    }
  }

  async updateMulSystemUser(
    params: QueryMulSystemUserParams,
    data4up: UpdateSystemUserParams,
  ) {
    try {
      const res = await this.systemUserModel.updateMany(params, data4up);
      if (res) return true;
      return false;
    } catch (err) {
      this.logger.printError(this.updateMulSystemUser.name, err);
      return false;
    }
  }

  async updateMulAuths(params: QueryMulAuthsParams, data4up: UpdateAuthType) {
    try {
      const res = await this.authModel.updateMany(params, {
        $set: data4up,
      });
      if (res) return true;
      return false;
    } catch (err) {
      this.logger.printError(this.updateMulAuths.name, err);
      return false;
    }
  }

  async deleteOneSystemUser(params: QuerySingleSystemUserParams) {
    try {
      const res = await this.systemUserModel.deleteOne(params);
      if (res) return true;
      return false;
    } catch (err) {
      this.logger.printError(this.deleteOneSystemUser.name, err);
      return false;
    }
  }

  async deleteMulSystemUsers(params: QueryMulSystemUserParams) {
    try {
      const res = await this.systemUserModel.deleteMany(params);
      if (res.deletedCount) return true;
      return false;
    } catch (err) {
      this.logger.printError(this.deleteMulSystemUsers.name, err);
      return false;
    }
  }

  async deleteOneAuth(params: QuerySingleAuthParamsType) {
    try {
      const res = await this.authModel.deleteOne(params);
      if (res.deletedCount) return true;
      return false;
    } catch (err) {
      this.logger.printError(this.deleteOneAuth.name, err);
      return false;
    }
  }
  async deleteMulAuth(params: QueryMulAuthsParams) {
    try {
      const res = await this.authModel.deleteMany(params);
      if (res.deletedCount) return true;
      return false;
    } catch (err) {
      this.logger.printError(this.deleteMulAuth.name, err);
      return false;
    }
  }
}
